package com.ontheroad.mysql.activity.service.app;

import cn.modoumama.page.PageObject;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.ontheroad.activity.model.*;
import com.ontheroad.activity.service.ActivitJoinApplyService;
import com.ontheroad.activity.service.ActivitService;
import com.ontheroad.activity.service.app.AppActivityService;
import com.ontheroad.api.request.ActivityRequest;
import com.ontheroad.api.response.ActivtiyListResponse;
import com.ontheroad.api.response.JoinApplyResponse;
import com.ontheroad.api.response.Response;
import com.ontheroad.core.util.DateUtils;
import com.ontheroad.core.util.SpringUtils;
import com.ontheroad.core.util.StringUtils;
import com.ontheroad.leanCloud.event.PushToUserEvent;
import com.ontheroad.leanCloud.model.PushType;
import com.ontheroad.leanCloud.service.LeanCloudService;
import com.ontheroad.mysql.activity.mapper.ActivityCommentMapper;
import com.ontheroad.mysql.activity.mapper.ActivityLikeMapper;
import com.ontheroad.mysql.activity.mapper.ActivityMapper;
import com.ontheroad.mysql.activity.mapper.ActivityTypeActMapper;
import com.ontheroad.system.entity.SysUser;
import com.ontheroad.system.service.SysUserService;
import com.ontheroad.user.model.UserModel;
import com.ontheroad.user.service.UserService;
import net.spy.memcached.MemcachedClient;
import org.apache.commons.collections.map.HashedMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * Created by kedong on 2017/9/23 0023.
 */
@Service
@Transactional
public class AppActivityServiceImpl implements AppActivityService {

    private Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    private ActivitService activitService;

    @Autowired
    private ActivityMapper activityMapper;

    @Autowired
    private ActivityLikeMapper activityLikeMapper;

    @Autowired
    private ActivityCommentMapper commentMapper;

    @Autowired
    private ActivityTypeActMapper activityTypeActMapper;

    @Autowired
    private ActivitJoinApplyService joinApplyService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private UserService userService;

    @Autowired
    private LeanCloudService leanCloudService;


    @Autowired
    private MemcachedClient memCachedClient;

    /**
     * 发布活动
     *
     * @param request
     * @return
     */
    @Override
    public Response publish(ActivityRequest request) throws Exception {
        Integer userId = request.getUserId().intValue();
        Response response = new Response();
        ActivityModel activityModel = new ActivityModel();
        activityModel.setAddress(request.getAddress());
        activityModel.setTitle(request.getTitle());
        activityModel.setCity(request.getCity());
        activityModel.setContent(request.getContent());
        activityModel.setCost(new BigDecimal(request.getCost()));
        activityModel.setCostType(request.getCostType());
        activityModel.setCreateUserId(userId);
        activityModel.setStartTime(new Date(request.getStartTime() * 1000));
        activityModel.setEndTime(new Date(request.getEndTime() * 1000));
        activityModel.setLimitCount(request.getLimitCount());
        activityModel.setSource(1);
        String images = request.getImages();
        activityModel.setImages(images);
        // 截取标题图片
        if (!StringUtils.isBlankString(images)) {
            if (images.contains(",")) {
                String imgs[] = images.split(",");
                activityModel.setTitleImage(imgs[0]);
            } else {
                activityModel.setTitleImage(images);
            }
        }
        activityModel.setCreateTime(new Date());
        UserModel user = userService.findById(userId);
        activityModel.setOfficial(user.getOfficial());
        activityMapper.insertModel(activityModel);
        // 类型
        String type = request.getType();
        if (!StringUtils.isBlankString(type)) {
            String types[] = null;
            if (type.contains(",")) {
                types = type.split(",");
            } else {
                types = new String[]{type};
            }
            List<Integer> actTypes = new ArrayList<>();
            for (String s : types) {
                actTypes.add(Integer.parseInt(s));
            }
            activitService.saveActTypes(actTypes, activityModel.getId());
        }


        /**
         * 创建群聊
         * 这里是在leancloud服务器上创建一个会话，是一个网络请求，属于耗时操作。
         * 但是该接口代码执行到这里为止，主要的业务逻辑已经处理成功，并不需要等待上述耗时操作完成后再将结果返回给客户端，因为这将增加客户端的等待时间
         * 因此这里将该操作放到一个单独的线程里去处理它，而接口程序则可以不需要等待直接返回结果给客户端
         * 至于创建会话的结果则可以通过通知的方式推送给客户端

         SpringUtils.publishEvent(
         new CreateSessionEvent("为活动创建群聊",
         activityModel.getTitle(),
         Lists.newArrayList(request.getUserId().intValue()),
         SessionType.ACTIVITY,
         activityModel.getId()));
         */
        /**
         * type:1  说明：（1：群聊，0：单聊）
         * name:活动名称
         * creater：创建者ID
         * logo：活动的图片地址
         */
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("type", 1);
        jsonObject.put("name", activityModel.getTitle());
        jsonObject.put("creater", activityModel.getCreateUserId());
        jsonObject.put("logo", activityModel.getTitleImage());
        // 创建群聊
        String objectId = leanCloudService.createSession(activityModel.getTitle(), jsonObject, Lists.newArrayList(request.getUserId().intValue()));
        activityModel.setObjectId(objectId);
        activitService.updateById(activityModel);

        // 推送
        try {
            // TODO 推送
            Map<String, Object> map = new HashMap<>();
            map.put("action", PushType.ACTIVITY.getValue());
            map.put("id", activityModel.getId());
            leanCloudService.push(activityModel.getTitle(), null, map);
        } catch (Exception e) {
            log.error("推送失败", e);
        }
        response.addResultData("activity", activityModel);
        return response;
    }

    @Override
    public Response detail(ActivityRequest request) throws Exception {
        Response response = new Response();
        Integer activityId = request.getActivityId();
        ActivityModel activity = activitService.findById(activityId);
        if (activity == null) {
            response.setCode(Response.CODE_FAILED);
            response.setMsg("活动不存在");
            return response;
        }
        response.addResultData("objectId", activity.getObjectId());
        // 图片
        response.addResultData("images", activity.getImages());
        // 标题
        response.addResultData("title", activity.getTitle());
        // 人数限制
        response.addResultData("limitCount", activity.getLimitCount());

        Map<String, Object> query = new HashMap<>();
        query.put("activityId", activity.getId());
        query.put("status", 1);
        List<ActivityJoinApplyModel> activityUserModels = joinApplyService.findModelsByCondition(query);
        // 已参与人数
        if (activityUserModels == null) {
            activityUserModels = new ArrayList<>();
        }
        response.addResultData("joinCount", activityUserModels.size());
        // 活动发起人
        ActivityJoinApplyModel created = new ActivityJoinApplyModel();
        created.setCreated(true);
        created.setUserId(activity.getCreateUserId());
        UserModel user = userService.findById(activity.getCreateUserId());
        created.setNick(user.getNick());
        created.setImage(user.getPic());
        activityUserModels.add(created);
        // 已参与用户列表
        response.addResultData("joinList", activityUserModels);
        // 官方标记,是否为官方活动
        response.addResultData("official", activity.getOfficial());
        // 目的地
        response.addResultData("address", activity.getAddress());
        // 费用类型
        response.addResultData("costType", activity.getCostType());
        // 费用数目
        response.addResultData("cost", activity.getCost());
        // 活动说明
        response.addResultData("content", activity.getContent());
        // 活动状态
        response.addResultData("state", activitService.getActivityState(activity));
        // 活动标签（类型）;
        response.addResultData("types", activityTypeActMapper.findModelsByActivityId(activity.getId()));
        // 活动开始时间
        response.addResultData("startTime", DateUtils.dateToTimestamp(activity.getStartTime()));
        // 活动结束时间
        response.addResultData("endTime", DateUtils.dateToTimestamp(activity.getEndTime()));
        response.addResultData("userId", activity.getCreateUserId());

        // 用户参与状态
        Long userId = request.getUserId();
        if (userId != null) {
            Integer joinState = joinApplyService.getJoinState(activity, userId.intValue());
            if (joinState == null) {
                joinState = -1;
            }
            response.addResultData("joinState", joinState);
        }
        return response;
    }

    /**
     * 活动报名接口
     * 报名成功，通知活动发起人审核
     *
     * @param request
     * @return
     * @throws Exception
     */
    @Override
    public Response joinApply(ActivityRequest request) throws Exception {
        Response response = new Response();

        Integer userId = request.getUserId().intValue();
        Integer activityId = request.getActivityId();


        ActivityJoinApplyModel joinApplyModel = new ActivityJoinApplyModel();
        joinApplyModel.setUserId(userId);
        joinApplyModel.setActivityId(activityId);
        List<ActivityJoinApplyModel> joinApplyModels = joinApplyService.getListByModel(joinApplyModel);
        joinApplyModel.setContent(request.getContent());
        joinApplyModel.setStatus(0);
        joinApplyModel.setCreateTime(new Date());
        if (joinApplyModels != null && joinApplyModels.size() > 0) {
            joinApplyModel.setId(joinApplyModels.get(0).getId());
            joinApplyService.updateById(joinApplyModel);
        } else {
            joinApplyService.insert(joinApplyModel);
        }
        /**
         * 报名成功，通知活动发起人审核
         */
        ActivityModel model = activitService.findById(activityId);
        if (model != null) {
            Map<String, Object> data = new HashMap<>();
            UserModel user = userService.findById(model.getCreateUserId());
            // 用户头像
            data.put("userIcon", user.getPic());
            // 用户昵称
            data.put("userName", user.getNick());
            String images = model.getImages();
            String img = "";
            if (org.apache.commons.lang3.StringUtils.isNotBlank(images)) {
                if (images.contains(",")) {
                    img = images.split(",")[0];
                } else {
                    img = images;
                }
            }
            //图片
            data.put("img", img);
            //时间
            data.put("time", DateUtils.dateToTimestamp(null));

            data.put("id", activityId);
            //通知类型
            data.put("action", PushType.JOINAPPLY.getValue());

            // 点赞动态推送
            SpringUtils.publishEvent(new PushToUserEvent("活动报名申请推送...", model.getCreateUserId(), data));
        }
        return response;
    }

    @Override
    public Response joinApplyList(ActivityRequest request) throws Exception {
        Integer userId = request.getUserId().intValue();
        List<JoinApplyResponse> list = activitService.getJoinApplyList(userId, request.getPageNum(), request.getPageSize());
        Response response = new Response();
        response.addResultData("list", list);
        return response;
    }

    @Override
    public Response approve(ActivityRequest request) throws Exception {
        Response response = new Response();
        Integer userId = request.getUserId().intValue();
        Integer activityId = request.getActivityId();
        Integer joinUserId = request.getJoinUserId();

        ActivityModel activity = activitService.findById(activityId);
        if (userId.intValue() == activity.getCreateUserId()) {

            ActivityJoinApplyModel joinApplyModel = new ActivityJoinApplyModel();
            joinApplyModel.setUserId(joinUserId);
            joinApplyModel.setActivityId(activityId);

            List<ActivityJoinApplyModel> list = joinApplyService.getListByModel(joinApplyModel);
            if (list != null && list.size() > 0) {
                joinApplyModel = list.get(0);
                joinApplyModel.setStatus(request.getState());

                joinApplyService.updateById(joinApplyModel);
                if (joinApplyModel.getStatus() == 1) {
                    /**
                     * 同意加入活动
                     * 将用户加入群聊
                     */
                    String objectId = activity.getObjectId();
                    leanCloudService.addUserToSession(objectId, joinUserId);
                }
            } else {
                response = Response.FAILED("该用户以取消报名申请");
            }
        } else {
            response = Response.FAILED("您不是该活动的管理员");
        }
        return response;
    }

    @Override
    public Response list(ActivityRequest request) throws Exception {
        Response response = new Response();
        // 活动列表
        List<ActivtiyListResponse> activtiyListResponses = getList(request);
        response.addResultData("activityList", activtiyListResponses);

        //类型列表
        List<ActivityTypeModel> typeModels = activitService.getTypeListByCondition(null);
        response.addResultData("typeList", typeModels);
        return response;
    }

    private List<ActivtiyListResponse> getList(ActivityRequest request) throws Exception {
        // 分页
        PageObject po = new PageObject();
        po.setCurrPage(request.getPageNum());
        po.setPageSize(request.getPageSize());
        // 查询条件
        String searchKey = request.getSearchKey();
        if (!StringUtils.isBlankString(searchKey)) {
            po.addCondition("searchKey", searchKey);
        }
        // 城市
        String city = request.getCity();
        if (!StringUtils.isBlankString(city)) {
            po.addCondition("addressLike", city);
        }
        // 费用类型
        Integer costType = request.getCostType();
        if (costType != null) {
            po.addCondition("costType", costType);
        }
        // 时间
        Integer dateType = request.getDateType();
        if (dateType != null) {
            Date searchStartTime = null;
            Date searchEndTime = null;
            switch (dateType) {
                case 1:
                    //本周
                    searchStartTime = DateUtils.getBeginDayOfWeek();
                    searchEndTime = DateUtils.getEndDayOfWeek();
                    break;
                case 2:
                    //下周
                    searchStartTime = DateUtils.getBeginDayOfNextWeek();
                    searchEndTime = DateUtils.getEndDayOfNextWeek();
                    break;
                case 3:
                    //下月
                    searchStartTime = DateUtils.getBeginDayOfMonth(1);
                    searchEndTime = DateUtils.getEndDayOfMonth(1);
                    break;
                case 4:
                    //自定义时间
                    if (request.getSearchStartTime() != null) {
                        searchStartTime = new Date(request.getSearchStartTime() * 1000);
                    }
                    if (request.getSearchEndTime() != null) {
                        searchEndTime = new Date(request.getSearchEndTime() * 1000);
                    }
                    break;
            }
            if (searchStartTime != null) {
                po.addCondition("searchStartTime", searchStartTime);
            }
            if (searchEndTime != null) {
                po.addCondition("searchEndTime", searchEndTime);
            }
        }
        boolean hasActivity = true;
        //类型
        Integer type = request.getSearchType();
        if (type != null) {
            List<Integer> activityIds = activitService.getActivityIdsByType(type);
            if (activityIds == null || activityIds.size() == 0) {
                hasActivity = false;
            }
            po.addCondition("ids", activityIds);
        }

        //好友参与的
        if (request.getFreindJoin()) {
            Integer userId = request.getUserId().intValue();
            //查询好友列表
            List<Integer> activityIds = activitService.getActivityIdsByFreindJoin(userId);
            if (activityIds == null || activityIds.size() == 0) {
                hasActivity = false;
            }
            po.addCondition("idsFreindJoin", activityIds);
        }
        po.addCondition("orderByClause", "create_time desc");
        List<ActivtiyListResponse> activtiyListResponses = new ArrayList<>();
        if (hasActivity) {
            List<ActivityModel> list = activitService.findModelsByCondition(po);
            activtiyListResponses = activitService.convertActivityList(list);
        }
        return activtiyListResponses;
    }

    @Override
    public Response search(ActivityRequest request) throws Exception {
        Response response = new Response();
        PageObject po = new PageObject();
        po.setCurrPage(request.getPageNum());
        po.setPageSize(request.getPageSize());
        String searchKey = request.getSearchKey();
        if (!StringUtils.isBlankString(searchKey)) {
            po.addCondition("searchKey", searchKey);
        }
        //类型
        Integer searchType = request.getSearchType();
        if (searchType != null) {
            List<Integer> activityIds = activitService.getActivityIdsByType(searchType);
            if (activityIds != null && activityIds.size() > 0) {
                po.addCondition("ids", activityIds);
            }
        }

        List<ActivtiyListResponse> activtiyListResponses = new ArrayList<>();
        if (po.getCondition().size() > 0) {
            List<ActivityModel> list = activitService.findModelsByCondition(po);
            activtiyListResponses = activitService.convertActivityList(list);
        }
        response.addResultData("activityList", activtiyListResponses);
        return response;
    }

    @Override
    public Response myActivityPublish(ActivityRequest request) throws Exception {
        Integer targetId = request.getTargetId();
        if (targetId == null) {
            targetId = request.getUserId().intValue();
        }
        PageObject pageObject = new PageObject();
        pageObject.setCurrPage(request.getPageNum());
        pageObject.setPageSize(request.getPageSize());
        pageObject.addCondition("createUserId", targetId);
        pageObject.addCondition("orderByClause", "create_time desc");

        UserModel user = userService.findById(targetId);
        String mobile = user.getMobile();
        SysUser sysUser = sysUserService.getObjectByMobile(mobile);
        if (sysUser != null) {
            pageObject.addCondition("orCreateSysId", sysUser.getUserId());
        }

        // 我发布的活动
        List<ActivityModel> activityModels = activitService.findModelsByCondition(pageObject);
        Response response = new Response();
        response.addResultData("list", activitService.convertActivityList(activityModels));
        return response;
    }

    @Override
    public Response myActivityJoin(ActivityRequest request) throws Exception {
        Integer targetId = request.getTargetId();
        if (targetId == null) {
            targetId = request.getUserId().intValue();
        }
        // 我参与的活动
        List<ActivityModel> list = joinApplyService.getMyActivity(Long.valueOf(targetId));
        Response response = new Response();
        response.addResultData("list", activitService.convertActivityList(list));
        return response;
    }

    @Override
    public Response delete(ActivityRequest request) throws Exception {
        Integer activityId = request.getActivityId();
        activitService.removeById(activityId);
        return new Response();
    }

    @Override
    public Response like(ActivityRequest request) throws Exception {
        Response response = new Response();
        Integer userId = request.getUserId().intValue();
        Integer activityId = request.getActivityId();

        // 先查询是否存在
        Map<String, Object> map = new HashedMap();
        map.put("userId", userId);
        map.put("activityId", activityId);
        List list = activityLikeMapper.findModelsByCondition(map);
        if (list != null || list.size() > 0) {
            // 已经点过赞了
            return response.addErrDetailInfo(1, "您已经点过赞了，不要重复操作", "");
        } else {
            ActivityLikeModel likeModel = new ActivityLikeModel();
            likeModel.setCreateTime(new Date());
            likeModel.setUserId(userId);
            likeModel.setActivityId(activityId);
            activityLikeMapper.insertModel(likeModel);
            response.addResultData("model", likeModel);
        }
        return response;
    }

    @Override
    public Response dissLike(ActivityRequest request) throws Exception {
        Response response = new Response();
        Integer userId = request.getUserId().intValue();
        Integer activityId = request.getActivityId();

        // 先查询是否存在
        Map<String, Object> map = new HashedMap();
        map.put("userId", userId);
        map.put("activityId", activityId);
        List<ActivityLikeModel> list = activityLikeMapper.findModelsByCondition(map);
        if (list != null || list.size() > 0) {
            for (ActivityLikeModel likeModel : list) {
                activityLikeMapper.deleteById(likeModel.getId());
            }
        }
        return response;
    }

    @Override
    public Response comment(ActivityRequest request) throws Exception {
        String content = request.getContent();
        Integer activityId = request.getActivityId();

        Date now = new Date();

        ActivityCommentModel commentModel = new ActivityCommentModel();
        commentModel.setCreateTime(now);
        commentModel.setUserid(request.getUserId().intValue());
        commentModel.setContent(content);
        commentModel.setActivityId(activityId);
        commentModel.setReplyedid(request.getReplyedid());
        commentMapper.insertModel(commentModel);
        Response response = Response.SUCCESS();
        response.addResultData("commentId", commentModel.getId());


        ActivityModel activityModel = activityMapper.getObjectById(activityId);
        if (activityModel != null) {
            Integer createUserId = activityModel.getCreateUserId();
            UserModel userModel = userService.findById(createUserId);
            Map<String, Object> data = new HashMap<>();
            // 用户头像
            data.put("userIcon", userModel.getPic());
            // 用户昵称
            data.put("userName", userModel.getNick());
            String images = activityModel.getImages();
            String img = "";
            if (org.apache.commons.lang3.StringUtils.isNotBlank(images)) {
                if (images.contains(",")) {
                    img = images.split(",")[0];
                } else {
                    img = images;
                }
            }
            //图片
            data.put("img", img);
            //时间
            data.put("time", DateUtils.dateToTimestamp(now));
            //内容
            data.put("content", content);
            //1、动态，2、约伴,3、活动
            data.put("type", 3);
            data.put("id", activityId);
            //通知类型
            data.put("action", PushType.COMMENT.getValue());

            // 评论动态推送
            SpringUtils.publishEvent(new PushToUserEvent("评论动态推送...", request.getUserId().intValue(), data));
        }

        return response;
    }
}
